from pathlib import Path
import random
import time
import itertools
import re
import json
import os

from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from bs4 import BeautifulSoup

from browser import Browser



class Parser(Browser):

    """ Этот класс представляет парсер """

    def __init__(self, data, proxy_list=None):

        self.display_browser = data[0]
        self.link = 'https://marketguru.io/competitors/categories'

        self.username = 'alena.borisova.00@internet.ru'    # Почта для входа
        self.password = '32231vwopD.'                      # Пароль от почты

        self.initial_category = data[1]           # Категория с которой начнется парсинг
        self.final_category = data[2]             # Категория на которой закончится парсинг
        self.count_subcategories = data[3] + 1    # Количество подкатегорий для парсинга
        self.count_pages = data[4]                # Количество страниц товаров для парсинга

        print(f'{self.initial_category}\n{self.final_category}\n{self.count_subcategories}\n{self.count_pages}')


    def wait(self, a=2, b=3.5):

        """ Чуть-чуть подождать """

        number = random.uniform(a, b)
        print(f'Ждем {number}\n')
        time.sleep(number)


    def convert_to_bs(self, browser):

        """ Получаем объект BeautifulSoup """

        html_source = browser.page_source
        page = BeautifulSoup(html_source, 'lxml')

        return page


    def get_saved_page(self, file_name):

        """ Открываем сохраненную страницу для парсинга и возвращаем ее """

        folder = Path('saved_html/')
        page = folder/file_name

        with open(page, 'r', encoding='utf-8') as file:

            text = file.read()
            page = BeautifulSoup(text, 'lxml')

            return page


    def get_configured_browser(self, link, proxy=None):

        """ Получаем настроенный браузер """

        browser = self.get_browser(self.display_browser)
        browser.get(link)
        browser.implicitly_wait(15)
        browser.maximize_window()

        return browser


    def check_if_this_is_a_product(self, element):

        """ Проверяем, является ли полученный элемент продуктом """

        if 'Артикул' in element: return 'Продукт'

        else: return 'Подкатегория'


    def write_to_json(self, category_name, new_data):

        """ Записываем в json """

        try:

            data = json.load(open('data.json'))

        except:

            data = {}

        data[category_name] = new_data

        with open('data.json', 'w', newline='', encoding='utf-8') as file:

            json.dump(data, file, indent=4, ensure_ascii=False)


    def get_products_subcategory(self, products):

        """ Получаем все продукты подкатегории """

        pass


    def convert_data_to_dictionary(self, category, names_subcategories_first_group, products_subcategories_first_group, names_subcategories_second_group, contents_subcategories_second_group, names_subcategories_third_group, products_subcategories_third_group, names_subcategories_fourth_group, products_subcategories_fourth_group):

        """ Преобразуем данные в словарь для того чтобы после добавить в json """

        def get_dictionary_first_subcategory(names_subcategories_first_group, products_subcategories_first_group):

            """ Создаем словарь из подкатегории первой группы """

            count = 0
            done = {}

            for name in names_subcategories_first_group:

                if name[-1] == 'Подкатегории':

                    done[name[0]] = 'В этой подкатегории находятся другие подкатегории'
                    continue

                done[name[0]] = products_subcategories_first_group[count]
                count += 1

            return done


        def get_dictionary_second_subcategory(names_subcategories_second_group, contents_subcategories_second_group):

            """ Создаем словарь из подкатегории второй группы """

            def get_desired_type_products(contents_subcategories_second_group):

                """ Получаем нужный вид продуктов подкатгеории второй группы """

                done_contents_subcategories_second_group = []
                contents_subcategories_second_group = [item for item in contents_subcategories_second_group if item]

                for item in contents_subcategories_second_group:

                    for i in item:

                        done_contents_subcategories_second_group.append(i)

                return done_contents_subcategories_second_group


            # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

            count = 0
            done = {}
            done_contents_subcategories_second_group = get_desired_type_products(contents_subcategories_second_group)

            for name in names_subcategories_second_group:

                if 'Подкатегории' in name[-1]:

                    done[name[0]] = 'В этой подкатегории есть еще подкатегория'
                    continue

                done[name[0]] = done_contents_subcategories_second_group[count]
                count += 1

            return done


        def get_dictionary_third_subcategory(names_subcategories_third_group, products_subcategories_third_group):

            """ Создаем словарь из подкатегории третьей группы """

            def get_temp_names_subcategories_third_group(names_subcategories_third_group):

                """ Получаем временный список для хранения всех названий подкатегори """

                result = []

                for all_names in names_subcategories_third_group:

                    for names in all_names:

                        for name in names:

                            result.append(name)

                return result


            def get_temp_products_subcategories_third_group(products_subcategories_third_group):

                """ Получаем временный список для хранения всех продуктов подкатегори """

                result = []

                for all_products in products_subcategories_third_group:

                    for products in all_products:

                        for product in products:

                            result.append(product)

                return result

            # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

            done = {}
            temp_names_subcategories_third_group = get_temp_names_subcategories_third_group(names_subcategories_third_group)
            temp_products_subcategories_third_group = get_temp_products_subcategories_third_group(products_subcategories_third_group)

            for name, product in itertools.zip_longest(temp_names_subcategories_third_group, temp_products_subcategories_third_group):

                name = '; '.join(name[0])
                done[name] = product

            return done


        def get_dictionary_fourth_subcategory(names_subcategories_fourth_group, products_subcategories_fourth_group):

            """ Создаем словарь из подкатегории четвертой группы """

            def get_names_in_desired_form_subcategories_fourth_group(names_subcategories_fourth_group):

                """ Получаем имена подкатегории четвертой группы в нужной форме """

                done_names_in_desired_form = []

                for all_names in names_subcategories_fourth_group:

                    for names in all_names:

                        if names == 'None': continue

                        for name in names:

                            done_names_in_desired_form.append(name)

                return done_names_in_desired_form


            def get_products_in_desired_form_subcategories_fourth_group(products_subcategories_fourth_group):

                """ Получаем продукты подкатегории четвертой группы в нужной форме """

                done_products_in_desired_form = []

                for all_products in products_subcategories_fourth_group:

                    for products in all_products:

                        for product in products:

                            if product is None: continue

                            done_products_in_desired_form.append(product)

                return done_products_in_desired_form


            # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

            counter = 0
            done = {}

            names_in_desired_form_subcategories_fourth_group = get_names_in_desired_form_subcategories_fourth_group(names_subcategories_fourth_group)

            print('names_in_desired_form_subcategories_fourth_group')
            print(names_in_desired_form_subcategories_fourth_group)
            print(len(names_in_desired_form_subcategories_fourth_group))
            print('names_in_desired_form_subcategories_fourth_group')

            products_in_desired_form_subcategories_fourth_group = get_products_in_desired_form_subcategories_fourth_group(products_subcategories_fourth_group)

            print('products_in_desired_form_subcategories_fourth_group')
            print(products_in_desired_form_subcategories_fourth_group)
            print(len(products_in_desired_form_subcategories_fourth_group))
            print('products_in_desired_form_subcategories_fourth_group')

            for name in names_in_desired_form_subcategories_fourth_group:

                if name[-1] == 'Подкатегории':

                    done[name[0]] = 'Подкатегория содержит другие подкатегории'
                    continue

                done[name[0]] = products_in_desired_form_subcategories_fourth_group[counter]
                counter += 1

            return done


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНЦИЙ

        data = {}
        category_name = '; '.join(category)
        data[category_name] = {}

        # ПЕРВАЯ ПОДКАТЕГОРИЯ
        dictionary_first_subcategory = get_dictionary_first_subcategory(names_subcategories_first_group, products_subcategories_first_group)
        print('dictionary_first_subcategory')
        print(dictionary_first_subcategory)
        print('dictionary_first_subcategory')

        # ВТОРАЯ ПОДКАТЕГОРИЯ
        dictionary_second_subcategory = get_dictionary_second_subcategory(names_subcategories_second_group, contents_subcategories_second_group)
        print('dictionary_second_subcategory')
        print(dictionary_second_subcategory)
        print('dictionary_second_subcategory')

        # ТРЕТЬЯ ПОДКАТЕГОРИЯ
        dictionary_third_subcategory = get_dictionary_third_subcategory(names_subcategories_third_group, products_subcategories_third_group)
        print('dictionary_third_subcategory')
        print(dictionary_third_subcategory)
        print('dictionary_third_subcategory')

        # ЧЕТВЕРТАЯ ПОДКАТЕГОРИЯ
        dictionary_fourth_subcategory = get_dictionary_fourth_subcategory(names_subcategories_fourth_group, products_subcategories_fourth_group)
        print('dictionary_fourth_subcategory')
        print(dictionary_fourth_subcategory)
        print('dictionary_fourth_subcategory')

#        ['Первая подкатегория': dictionary_first_subcategory],
#        ['Вторая подкатегория': dictionary_second_subcategory],
#        ['Третья подкатегория': dictionary_third_subcategory],
#        ['Четвертая подкатегория': dictionary_fourth_subcategory]

        data = {
            'Первая подкатегория': dictionary_first_subcategory,
            'Вторая подкатегория': dictionary_second_subcategory,
            'Третья подкатегория': dictionary_third_subcategory,
            'Четвертая подкатегория': dictionary_fourth_subcategory
        }

        self.write_to_json(category_name, data)



    def convert_data_to_json_format(self, category):

        """ Преобразовываем данные в формат для json """

        def get_subcategories_second_group(done_name_subcategories_first_group, subcategories_first_group):

            """ Получаем подкатегорию второй группы """

            def get_name_subcategory_second_group(subcategory_second_group):

                """ Получаем название подкатегории вторйо группы """

                name_subcategory = '; '.join(subcategory_second_group[:8])

                try:

                    content = '; '.join(subcategory_second_group[-1][0])
                    return [name_subcategory, 'Продукты']

                except:

                    return [name_subcategory, 'Подкатегории']


            name_subcategories_second_group = []
            content_subcategories_second_group = []

            try:

                data = subcategories_first_group[-1][0]

            except:

                return ['иди нахуй']

            for subcategory_second_group in data:

                name_subcategory = get_name_subcategory_second_group(subcategory_second_group)
                name_subcategories_second_group.append(name_subcategory)
                content_subcategories_second_group.append(subcategory_second_group[-1])

            return [name_subcategories_second_group, content_subcategories_second_group]


        def get_subcategories_third_group(content_subcategories_second_group):

            """ Забираем содержимое подкатегории третьей группы """

            def get_names_subcategories_third_group(element_subcategory_second_group):

                """ Получаем имена подкатегорий третьей группы """

                done_names_subcategories_third_group = []

                for subcategory_third_group in element_subcategory_second_group[0]:

                    try:

                        first_entry = '; '.join(subcategory_third_group[-1][0])  # Проверяем, является ли содержимое третьей группы сразу продуктами

                        name_subcategory_third_group = subcategory_third_group[:8]
                        done_names_subcategories_third_group.append([name_subcategory_third_group, 'Продукты'])

                    except:

                        name_subcategory_third_group = subcategory_third_group[:8]
                        done_names_subcategories_third_group.append([name_subcategory_third_group, 'Подкатегории'])


                return done_names_subcategories_third_group


            def get_contents_subcategories_third_group(element_subcategory_second_group):

                """ Получаем содержимое подкатегории третьей группы """

                done_contents_subcategories_third_group = []

                for subcategory_third_group in element_subcategory_second_group[0]:

                    content_subcategory_third_group = subcategory_third_group[-1]
                    done_contents_subcategories_third_group.append(content_subcategory_third_group)

                return done_contents_subcategories_third_group


            # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

            done_products_subcategory_second_group = []
            done_names_subcategories_third_group = []
            done_contents_subcategories_third_group = []

            for element_subcategory_second_group in content_subcategories_second_group:

                if element_subcategory_second_group is None: continue

                print('element_subcategory_second_group')
                print(element_subcategory_second_group)
                print(len(element_subcategory_second_group))
                print('element_subcategory_second_group')

                try:

                    first_entry = ' '.join(element_subcategory_second_group[0])
                    well_what = self.check_if_this_is_a_product(first_entry)

                    if well_what == 'Продукт':

                        done_products_subcategory_second_group.append(element_subcategory_second_group)

                except Exception as e:

                    print('e')
                    print(e)
                    print('e')

                    names_subcategories_third_group = get_names_subcategories_third_group(element_subcategory_second_group)        # Имена подкатегорий третьей группы
                    contents_subcategories_third_group = get_contents_subcategories_third_group(element_subcategory_second_group)  # Содержимое подкатегорий третьей группы

                    done_names_subcategories_third_group.append(names_subcategories_third_group)
                    done_contents_subcategories_third_group.append(contents_subcategories_third_group)

            return [done_products_subcategory_second_group, done_names_subcategories_third_group, done_contents_subcategories_third_group]


        def get_subcategories_fourth_group(contents_subcategories_third_group):

            """ Забираем содержимое подкатегории четвертой группы """

            def find_out_the_content(contents_subcategories_third_group):

                """ Узнаем какое содержимое в подкатегории третьей группы """

                try:

                    first_entry = ' '.join(contents_subcategories_third_group[0][0][0])

                    return 'Продукты'

                except:

                    return 'Подкатегории'


            def get_list_products_third_subcategory(contents_subcategories_third_group):

                """ Приводим данные в нужный вид """

                result = []

                for products_subcategory_third_group in contents_subcategories_third_group:

                    intermediate_list = []

                    for products in products_subcategory_third_group:

                        intermediate_list.append(products)

                    result.append(intermediate_list)

                return result


            def get_name_subcategory_fourth_group(content_subcategory_fourt_group):

                def get_name_subcategory(content):

                    """ Получаем название подкатегории """

                    name_subcategory = content[:8]
                    name_subcategory = '; '.join(name_subcategory)

                    return name_subcategory


                def get_content_subcategory(content):

                    """ Получаем содержимое подкатегории """

                    try:

                        content_subcategory = content[-1][0]
                        content_subcategory = '; '.join(content_subcategory)

                        return 'Продукты'

                    except:

                        return 'Подкатегории'

                result = []


                for content in content_subcategory_fourth_group:

                    name_subcategory = get_name_subcategory(content)
                    content_subcategory = get_content_subcategory(content)

                    done_name = [name_subcategory, content_subcategory]
                    result.append(done_name)

                return result

            def get_products_subcategory_fourth_group(content_subcategory_fourth_group):

                """ Получаем продукты подкатегории четвертой группы """

                all_products = []

                for products in content_subcategory_fourth_group:

                    all_products.append(products[-1])

                return all_products


            # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

            products_subcategories_third_group = []
            names_subcategories_fourth_group = []
            products_subcategories_fourth_group = []

            well_what = find_out_the_content(contents_subcategories_third_group)

            if well_what == 'Продукты':

                list_products_third_subcategories = get_list_products_third_subcategory(contents_subcategories_third_group)

                return ['Продукты', list_products_third_subcategories]

            print('contents_subcategories_third_group_kqiwkl')
            print(contents_subcategories_third_group)
            print(len(contents_subcategories_third_group))
            print('contents_subcategories_third_group_kqiwkl')

            for main in contents_subcategories_third_group[0]:

                if main is None:

                    names_subcategories_fourth_group.append('None')
                    continue

                for content_subcategory_fourth_group in main:

                    print('content_subcategory_fourth_group')
                    print(content_subcategory_fourth_group)
                    print(len(content_subcategory_fourth_group))
                    print('content_subcategory_fourth_group')

                    name_subcategory_fourth_group = get_name_subcategory_fourth_group(content_subcategory_fourth_group)
                    names_subcategories_fourth_group.append(name_subcategory_fourth_group)

                    print('name_subcategory_fourth_group')
                    print(name_subcategory_fourth_group)
                    print(len(name_subcategory_fourth_group))
                    print('name_subcategory_fourth_group')

                    products_subcategory_fourth_group = get_products_subcategory_fourth_group(content_subcategory_fourth_group)
                    products_subcategories_fourth_group.append(products_subcategory_fourth_group)

            return [names_subcategories_fourth_group, products_subcategories_fourth_group]


        def get_products_subcategories_first_group(subcategories_first_group):

            """ Забираем продукты подкатегории первой групы если такое есть """

            print('subcategories_first_group-jlksdf')
            print(subcategories_first_group)
            print(len(subcategories_first_group))
            print('subcategories_first_group-jlksdf')

            try:

                first_entry = ' '.join(subcategories_first_group[2][0])

                if 'Артикул' in first_entry: return ['Продукты', subcategories_first_group[2]]

            except:

                return ['Подкатегории']


        def get_name_subcategories_first_group(subcategories_first_group):

            """ Получаем название подкатегории первой группы """

            def get_temp_name_subcategory(subcategories_first_group):

                """ Получаем само название подкатегории первой группы """

                name = subcategories_first_group[1]
                name = '; '.join(name)

                return name


            def get_content_subcategory(subcategories_first_group):

                """ Получаем содержимое подкатегории первой группы """

                try:

                    first_entry = '; '.join(subcategories_first_group[-1][0])

                    return 'Продукты'

                except:

                    return 'Подкатегории'


            def get_done_name_subcategory(name_subcategory, content_subcategory):

                """ Получаем готовое имя подкатегории первой групы """

                done_name_subcategory = [name_subcategory, content_subcategory]

                return done_name_subcategory


            # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

            name_subcategory = get_temp_name_subcategory(subcategories_first_group)
            content_subcategory = get_content_subcategory(subcategories_first_group)
            done_name_subcategory = get_done_name_subcategory(name_subcategory, content_subcategory)

            return done_name_subcategory


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        category_name = '; '.join(category[0][0])      # Название категории
        done_name_subcategories_first_group = []       # Названия подкатегорий первой группы
        done_products_subcategories_first_group = []

        done_name_subcategories_second_group = []      # Названия подкатегорий второй группы
        done_contents_subcategories_second_group = []  # Продукты подкатегории второй группы

        done_name_subcategories_third_group = []       # Названия подкатегорий третьей группы
        done_products_subcategories_third_group = []   # Продукты подкатегорий третьей группы

        done_names_subcategories_fourth_group = []     # Названия подкатегорий четвертой группы
        done_products_subcategories_fourth_group = []  # Продукты подкатегорий четвертой группы

        for subcategories_first_group in category:

            print('subcategories_first_group_8jfd')
            print(subcategories_first_group)
            print(len(subcategories_first_group))
            print('subcategories_first_group_8jfd')

            # ПОДКАТЕГОРИИ ПЕРВОЙ ГРУППЫ
            name_subcategories_first_group = get_name_subcategories_first_group(subcategories_first_group)           # Получаем названия подкатегорий первой группы
            done_name_subcategories_first_group.append(name_subcategories_first_group)       # Добавляем покдатегории первой группы в список

            products_subcategory_first_group = get_products_subcategories_first_group(subcategories_first_group)

            print('products_subcategory_first_group')
            print(products_subcategory_first_group)
            print(len(products_subcategory_first_group))
            print('products_subcategory_first_group')

            well_what_subcategory_first_group = products_subcategory_first_group[0]
            if well_what_subcategory_first_group == 'Продукты':

                done_products_subcategories_first_group.append(products_subcategory_first_group[-1])
                continue

            # ПОДКАТЕГОРИИ ВТОРОЙ ГРУППЫ
            data_subcategories_second_group = get_subcategories_second_group(done_name_subcategories_first_group, subcategories_first_group)  # Подкатегории второй группы
            if data_subcategories_second_group[0] == 'Продукты':

                done_contents_subcategories_second_group.append(data_subcategories_second_group[1])
                continue

            if len(data_subcategories_second_group) == 1: continue
            name_subcategories_second_group = data_subcategories_second_group[0]
            contents_subcategories_second_group = data_subcategories_second_group[1]
            [done_name_subcategories_second_group.append(item) for item in name_subcategories_second_group]  # Добавили названиея подкатегорий второй группы

            # ПОДКАТЕГОРИИ ТРЕТЬЕЙ ГРУППЫ
            data_subcategories_third_group = get_subcategories_third_group(contents_subcategories_second_group)
            products_subcategory_second_group = data_subcategories_third_group[0]
            names_subcategories_third_group = data_subcategories_third_group[1]
            contents_subcategories_third_group = data_subcategories_third_group[2]

            done_contents_subcategories_second_group.append(products_subcategory_second_group)
            done_name_subcategories_third_group.append(names_subcategories_third_group)

            if not contents_subcategories_third_group: continue

            print('data_subcategories_third_group')
            print(data_subcategories_third_group)
            print(len(data_subcategories_third_group))
            print('data_subcategories_third_group')

            print('contents_subcategories_third_group')
            print(contents_subcategories_third_group)
            print(len(contents_subcategories_third_group))
            print('contents_subcategories_third_group')

            # ПОДКАТЕГОРИИ ЧЕТВЕРТОЙ ГРУППЫ
            data_subcategories_fourth_group = get_subcategories_fourth_group(contents_subcategories_third_group)

            if data_subcategories_fourth_group[0] == 'Продукты':

                done_products_subcategories_third_group.append(data_subcategories_fourth_group[1])
                continue

            names_subcategories_fourth_group = data_subcategories_fourth_group[0]
            products_subcategories_fourth_group = data_subcategories_fourth_group[1]

            done_names_subcategories_fourth_group.append(names_subcategories_fourth_group)
            done_products_subcategories_fourth_group.append(products_subcategories_fourth_group)
            print('data_subcategories_fourth_group')
            print(data_subcategories_fourth_group)
            print(len(data_subcategories_fourth_group))
            print('data_subcategories_fourth_group')


        # КАТЕГОРИЯ
        print('category_name_two')
        print(category[0][0])
        print('category_name_two')

        # ПРЕВАЯ ПОДКАТЕГОРИЯ
        print('done_name_subcategories_first_group_jkdfs')
        print(done_name_subcategories_first_group)
        print(len(done_name_subcategories_first_group))
        print('done_name_subcategories_first_group_jkdfs')

        print('done_products_subcategories_first_group')
        print(done_products_subcategories_first_group)
        print(len(done_products_subcategories_first_group))
        print('done_products_subcategories_first_group')

        # ВТОРАЯ ПОДКАТЕГОРИЯ
        print('done_name_subcategories_second_group_kjsfd')
        print(done_name_subcategories_second_group)
        print(len(done_name_subcategories_second_group))
        print('done_name_subcategories_second_group_kjsfd')

        print('done_contents_subcategories_second_group')
        print(done_contents_subcategories_second_group)
        print(len(done_contents_subcategories_second_group))
        print('done_contents_subcategories_second_group')

        # ТРЕТЬЕЯ ПОДКАТЕГОРИЯ
        print('done_name_subcategories_third_group_jlkfsd')
        print(done_name_subcategories_third_group)
        print(len(done_name_subcategories_third_group))
        print('done_name_subcategories_third_group_jlkfsd')

        print('done_products_subcategories_third_group_oiwe')
        print(done_products_subcategories_third_group)
        print(len(done_products_subcategories_third_group))
        print('done_products_subcategories_third_group_oiwe')

        # ЧЕТВЕРТАЯ ПОДКАТЕГОРИЯ
        print('done_names_subcategories_fourth_group')
        print(done_names_subcategories_fourth_group)
        print(len(done_names_subcategories_fourth_group))
        print('done_names_subcategories_fourth_group')

        print('done_products_subcategories_fourth_group')
        print(done_products_subcategories_fourth_group)
        print(len(done_products_subcategories_fourth_group))
        print('done_products_subcategories_fourth_group')

        self.convert_data_to_dictionary(
            category[0][0],
            done_name_subcategories_first_group,
            done_products_subcategories_first_group,
            done_name_subcategories_second_group,
            done_contents_subcategories_second_group,
            done_name_subcategories_third_group,
            done_products_subcategories_third_group,
            done_names_subcategories_fourth_group,
            done_products_subcategories_fourth_group
        )


    def login_to_site(self, browser):

        """ Авторизируемся на сайте """

        def choose_authorization_method(browser):

            """ Выбираем способ авторизации """

            button = browser.find_element(
                By.XPATH,
                '//span[contains(text(), "Email")]'
            )
            button.click()

            browser.implicitly_wait(10)


        def enter_username(browser):

            """ Вводим логин """

            login_field = browser.find_element(
                By.XPATH,
                '//input[@type="email"]'
            )

            login_field.click()
            login_field.clear()

            self.wait(.5, .7)

            login_field.send_keys(self.username)

            self.wait(.6, 1)


        def enter_password(browser):

            """ Вводим пароль """

            password_field = browser.find_element(
                By.XPATH,
                '//input[@type="password"]'
            )

            password_field.click()
            password_field.clear()

            self.wait(.5, .7)

            password_field.send_keys(self.password)

            self.wait(.6, .7)


        def click_login_button(browser):

            """ Нажимаем кнопку войти """

            login_button = browser.find_element(
                By.XPATH,
                '//button/span[contains(text(), "Войти")]'
            )
            login_button.click()


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        browser.implicitly_wait(50)

        choose_authorization_method(browser)
        enter_username(browser)
        enter_password(browser)
        click_login_button(browser)

        browser.implicitly_wait(50)


    def get_list_main_categories(self, browser):

        """ Получаем список главных категорий """

        def get_list_categories_selenium(browser):

            """ Получаем список главных категорий в виде объектов selenium """

            list_categories = browser.find_elements(
                By.XPATH,
                '//div[@class="container"]//datatable-selection/datatable-scroller[@class="datatable-scroll"]/datatable-row-wrapper'
            )

            return list_categories


        def get_list_categories(list_categories_selenium):

            """ Получаем список главных категорий в виде обычного текста """

            done_list_categories = []

            list_categories = [category.text for category in list_categories_selenium]

            for category in list_categories:

                entry = category.split('\n')
                entry = entry[:-1]
                done_list_categories.append([entry])

            return done_list_categories


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        list_categories_selenium = get_list_categories_selenium(browser)
        list_categories = get_list_categories(list_categories_selenium)

        return list_categories, list_categories_selenium


    def click_on_main_button(self, browser, category_number, list_main_categories_selenium):

        """ Нажимаем на кнопку 'Подробнее' главной категории """

        def move_to_desired_element(browser, selected_category):

            """ Перемещаемся к нужной категории """

            action = ActionChains(browser)
            action.move_to_element(selected_category)
            action.perform()

            browser.execute_script("window.scrollBy(0, 50)")

            browser.implicitly_wait(15)
            self.wait(.5, 1)


        def click_on_button(selected_category):

            """ Нажать на кнопку 'Подробнее' """

            selected_category.click()

            browser.implicitly_wait(20)
            self.wait(.5, 1)


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        if len(list_main_categories_selenium) == category_number: return 'Категории закончились'

        selected_category = list_main_categories_selenium[category_number]  # Выбираем нужную категорию
        move_to_desired_element(browser, selected_category)
        click_on_button(selected_category)

        self.wait(.5, 1)

        return selected_category.text.split('\n')[:8]


    def get_list_first_group_subcategories(self, browser):

        """ Получаем список из подкотегорий первой группы """

        def move_to_last_subcategory(browser):

            """ Перемещемся к последней подкатегории """

            browser.implicitly_wait(15)

            last_subcategory = browser.find_element(
                By.XPATH,
                '//datatable-row-wrapper[@class="datatable-row-wrapper"]//datatable-row-wrapper[@class="datatable-row-wrapper"][last()]'
            )

            action = ActionChains(browser)
            action.move_to_element(last_subcategory)
            action.perform()


        def get_list_subcategories(browser):

            """ Получаем список подкатегорий первой группы """

            done_list_subcategories = []

            list_subcategories = browser.find_elements(
                By.XPATH,
                '//datatable-body[@class="datatable-body"]//datatable-body[@class="datatable-body"]//datatable-scroller[@class="datatable-scroll"]/datatable-row-wrapper'
            )

            for subcategory in list_subcategories:

                entry = subcategory.text
                entry = entry.split('\n')
                entry = entry[:-1]
                done_list_subcategories.append([entry]) # Вот тут

            return done_list_subcategories


        def get_list_links(browser):

            """ Получаем список ссылок подкатегорий первой группы """

            list_links = browser.find_elements(
                By.XPATH,
                '//datatable-body[@class="datatable-body"]//datatable-body[@class="datatable-body"]//datatable-scroller[@class="datatable-scroll"]/datatable-row-wrapper//a[contains(text(), "Подробнее")]'
            )

            done_list_links = [link.get_attribute('href') for link in list_links]

            return done_list_links


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        move_to_last_subcategory(browser)
        list_subcategories = get_list_subcategories(browser)
        list_links = get_list_links(browser)

        return (list_subcategories, list_links)


    def combine_main_category_with_subcategory(self, list_main_categories, list_subcategories_first_group, category_number):

        """ Объединяем главную категорию с подкатегориями первой группы """

        def combine_categories(main_category, list_subcategories_first_group):

            """ Объединяем категории """

            main_category.append(list_subcategories_first_group)


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        main_category = list_main_categories[category_number]
        combine_categories(main_category, list_subcategories_first_group)

        return main_category


    def get_list_products(self, browser):

        """ Получаем продукты с подкатегории """

        def scroll_down_page(browser):

            """ Листаем вниз страницы """

            last_element = browser.find_element(
                By.XPATH,
                '//datatable-row-wrapper[@class="datatable-row-wrapper"][last()]'
            )

            action = ActionChains(browser)
            action.move_to_element(last_element)
            action.perform()

            browser.execute_script("window.scrollBy(0, 100)")

            browser.implicitly_wait(15)
            self.wait(.3, .7)


        def get_all_products(browser):

            """ Получаем продукты со страницы """

            def get_products(browser):

                """ Получаем продукты """

                done_products = []

                products_selenium = browser.find_elements(
                    By.XPATH,
                    '//datatable-row-wrapper[@class="datatable-row-wrapper"]'
                )

                for item in products_selenium:

                    entry = item.text
                    entry = entry.split('\n')
                    entry = entry[:-1]

                    done_products.append(entry)

                return done_products


            def get_product_links(browser):

                """ Получаем ссылка на каждый продукт """

                done_links = []

                links_selenium = browser.find_elements(
                    By.XPATH,
                    '//datatable-row-wrapper[@class="datatable-row-wrapper"]//a/b/..'
                )

                for item in links_selenium:

                    link = item.get_attribute('href')
                    done_links.append(link)

                return done_links


            def get_product_image(browser):

                """ Получаем ссылку на изображение продукта """

                done_image = []

                images_selenium = browser.find_elements(
                    By.XPATH,
                    '//datatable-row-wrapper[@class="datatable-row-wrapper"]//app-product-image//img'
                )

                for item in images_selenium:

                    image = item.get_attribute('src')
                    done_image.append(image)

                return done_image


            def combine_products_and_links(products, links, images):

                """ Совмещаем продукты с ссылками """

                for product, link, image in itertools.zip_longest(products, links, images):

                    product.append(link)
                    product.append(image)

                return products


            # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

            products = get_products(browser)
            links = get_product_links(browser)
            images = get_product_image(browser)

            result = combine_products_and_links(products, links, images)

            print('result')
            print(result)
            print(len(result))
            print('result')

            return result


        def go_to_next_page(browser):

            """ Переходим на следующую страницу """

            try:

                next_page_button = browser.find_element(
                    By.XPATH,
                    '//ul[@class="pager"]//li[@class="pages active"]/following::li[not(contains(@class, "disabled"))][last()-1]'
                ).click()

                return 'Продолжаем'

            except:

                return 'Закончились'


        def combine_all_products(list_products):

            """ Совмещаем все товары """

            combined_products = []

            for products in list_products:

                for product in products:

                    combined_products.append(product)

            return combined_products


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        list_products = []
        count = 0

        while True:

            if count == self.count_pages: break  # Количестов подкатегорий которое будет забираться
            scroll_down_page(browser)                         # Листаем вниз страницы
            products = get_all_products(browser)              # Получаем продукты со страницы

            well_what = go_to_next_page(browser)              # Переходим на следующую страницу
            list_products.append(products)                    # Сохраняем список товаров с одной страницы

            if well_what == 'Закончились': break              # Проверяем, идти на следующую страницу или нет
            count += 1

        done_list_products = combine_all_products(list_products)  # Объединяем прдукты

        return done_list_products


    def check_whats_on_page(self, browser):

        """ Проверяем что на странице """

        browser.implicitly_wait(50)
        self.wait(.5, .6)

        try:

            element = browser.find_element(
                By.XPATH,
                '//datatable-row-wrapper[@class="datatable-row-wrapper"][1]'
            ).text

            if 'Артикул' in element: return 'Продукты'
            else: return 'Подкатегории'

        except:

            element = browser.find_element(
                By.XPATH,
                '//div[contains(text(), "Товары не найдены")]'
            )

            return 'Товары не найдены'


    def open_subcategory_in_new_tab(self, browser, subcategory):

        """ Открываем подкатегорию в новой вкладке """

        def move_to_subcategory(browser, subcategory):

            """ Перемещаемся к подкатегории """

            action = ActionChains(browser)
            action.move_to_element(subcategory)
            action.perform()

            browser.execute_script("window.scrollBy(0, 50)")


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        move_to_subcategory(browser, subcategory)
        self.wait(.5, 1)
        subcategory.click()
        self.wait(.5, 1)
        browser.implicitly_wait(5)

        windows = browser.window_handles
        browser.switch_to.window(windows[-1])


    def close_new_tab(self, browser):

        """ Закрываем открывшуюся вкладку с подкатегорией """

        self.wait(.5, 1)
        browser.implicitly_wait(5)

        browser.close()

        self.wait(.5, 1)
        browser.implicitly_wait(5)

        windows = browser.window_handles
        browser.switch_to.window(windows[-1])


    def get_subcategories_third_group(self, browser):

        """ Получаем подкатегории третьей группы """

        def get_list_subcategories(browser):

            """ Получаем список подкатегорий третьей группы """

            done_list_subcategories = []

            list_subcategories_selenium = browser.find_elements(
                By.XPATH,
                '//datatable-row-wrapper[@class="datatable-row-wrapper"]'
            )
            list_subcategories = [subcategory.text for subcategory in list_subcategories_selenium]

            for subcategory in list_subcategories:

                entry = subcategory.split('\n')
                done_list_subcategories.append(entry)  # Вот тут

            return done_list_subcategories, list_subcategories_selenium


        def get_list_products_third_subcategories(browser, list_subcategories_selenium):

            """ Получаем список продуктов всех подкатегорий третьей группы """

            list_products_third_subcategories = []

            for i, subcategory in enumerate(list_subcategories_selenium, 1):

                if i == self.count_subcategories: break  # Количество подкатегорий для парсинга

                text = subcategory.text

                self.open_subcategory_in_new_tab(browser, subcategory)
                well_what = self.check_whats_on_page(browser)

                if well_what == 'Подкатегории':

                    subcategories_fourth_group = self.get_subcategories_third_group(browser)
                    list_products_third_subcategories.append(subcategories_fourth_group)

                    self.close_new_tab(browser)

                elif well_what == 'Продукты':

                    products = self.get_list_products(browser)          # Собираем их
                    list_products_third_subcategories.append(products)  # И добавляем в общий список

                    self.close_new_tab(browser)                         # Далее, закрываем эту подкатегорию

                elif well_what == 'Товары не найдены':

                    list_products_third_subcategories.append(['Товары не найдены'])
                    self.close_new_tab(browser)                         # Далее, закрываем эту подкатегорию


            return list_products_third_subcategories


        def combine_name_and_products(list_subcategories, list_products_third_subcategories):

            """ Объединяем название подкатегории и список их товаров """

            combined_data = []

            for subcategories, list_products in itertools.zip_longest(list_subcategories, list_products_third_subcategories):

                subcategories.append(list_products)
                combined_data.append(subcategories)

            return combined_data


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        result = []

        list_subcategories, list_subcategories_selenium = get_list_subcategories(browser)
        list_products_third_subcategories = get_list_products_third_subcategories(browser, list_subcategories_selenium)
        combined_data = combine_name_and_products(list_subcategories, list_products_third_subcategories)

        result.append(combined_data)

        return result


    def working_with_subcategories_second_group(self, browser, list_links_subcategories_first_group, subcategory_number):

        """ Работаем с подкатегориями второй группы """

        def open_subcategory_second_group(browser, list_links_subcategories_first_group, subcategory_number):

            """ Открываем подкатегорию второй группы """

            if len(list_links_subcategories_first_group) == subcategory_number: return ['Подкатегории закончились']

            self.wait(.4, .8)

            link_subcategory = list_links_subcategories_first_group[subcategory_number]
            #browser.get(link_subcategory)

            browser.quit()
            browser = self.get_configured_browser(link=link_subcategory)
            self.login_to_site(browser)

            return [browser]


        # ВЫШЕ ОПРЕДЕЛЕНИЕ ФУНКЦИЙ

        result = []

        while True:


            data = open_subcategory_second_group(browser, list_links_subcategories_first_group, subcategory_number)
            if data[0] == 'Подкатегории закончились': break

            browser = data[0]

            well_what = self.check_whats_on_page(browser)
            if well_what == 'Продукты':

                products = self.get_list_products(browser)
                result.append(products)

            elif well_what == 'Подкатегории':

                subcategories_third_group = self.get_subcategories_third_group(browser)
                result.append(subcategories_third_group)

            elif well_what == 'Товары не найдены':

                result.append(['Товары не найдены'])


            browser.quit()
            subcategory_number += 1
            #if 6 == subcategory_number: break
            self.wait(1, 1.5)

        return result


    def add_to_main_category(self, combined_category_with_subcategory, subcategories_second_group, current_category):

        """ Совмещаем главуню категорию с остальными подкатегориями """

        result = []

        for combined_category, subcategories in itertools.zip_longest(combined_category_with_subcategory[1], subcategories_second_group):

            combined_category.append(subcategories)
            combined_category.insert(0, current_category)
            result.append(combined_category)

        self.convert_data_to_json_format(result)

        return result


    def start_parsing(self):

        """ Начать парсинг """

        category_number = self.initial_category     # 8
        subcategory_number = 0   # Тут
        result = []              # Тут складываются все продукты с кнопки 'Подробнее'

        while True:

            if category_number == self.final_category: break
            #if subcategory_number == 8: break

            browser = self.get_configured_browser(link=self.link)  # Получаем браузер для парсинга главной категории

            self.login_to_site(browser)                            # Авторизируемся на сайте

            list_main_categories, list_main_categories_selenium = self.get_list_main_categories(browser)  # Получаем список из главных категорий
            current_category = self.click_on_main_button(browser, category_number, list_main_categories_selenium)            # Нажимаем на кнопку 'Подробнее'

            if current_category == 'Категории закончились': break

            list_subcategories_first_group, list_links_subcategories_first_group = self.get_list_first_group_subcategories(browser)  # получаем контент из подкатегории первой группы

            combined_category_with_subcategory = self.combine_main_category_with_subcategory(list_main_categories, list_subcategories_first_group, category_number)  # Совмещаем главную категорию с подкатегориями первой группы

            result.append(combined_category_with_subcategory)

            subcategories_second_group = self.working_with_subcategories_second_group(browser, list_links_subcategories_first_group, subcategory_number)

            #if subcategories_second_group == 'Подкатегории закончились': break

            done = self.add_to_main_category(combined_category_with_subcategory, subcategories_second_group, current_category)
            result.append(done)

            time.sleep(5)

            browser.quit()                                         # После парсинга одной главной категории - закрываем его
            category_number += 1
